package com.lucifer.d.security.transfer;

import com.alibaba.fastjson.JSON;
import com.lucifer.d.security.model.SecurityConfigModel;
import com.lucifer.d.security.util.TokenDecode;
import com.lucifer.d.util.RedissonUtil;
import com.lucifer.d.util.SnowflakeIdWorker;
import com.lucifer.d.util.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author Lucifer
 */
@Data
public class SignTransfer {

    /**
     * sign模板
     */
    private final static String signTemplate = "SignVerify:Sign 123456789";

    @Autowired
    private RedissonClient redissonClient;

    private HttpServletRequest request;

    private SecurityConfigModel securityConfigModel;

    public SignTransfer(SecurityConfigModel securityConfigModel) {
        if (securityConfigModel.getOnSecurity()){
            try {
                // 特殊过滤载体配置验证
                if (securityConfigModel.getSignMsg() == null){
                    if (!StringUtil.isEmpty(securityConfigModel.getSignMsgClass())){
                        securityConfigModel.setSignMsg(Class.forName(securityConfigModel.getSignMsgClass()));
                    }else {
                        // 允许忽视特殊过滤载体配置
//                    throw new LuciferSecurityException("特殊过滤载体配置错误");
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        this.securityConfigModel = securityConfigModel;
    }

    /**
     * 通过security黑盒子获取用户信息
     *
     * @return
     */
    public Object getSecurityUser(){
        // 获取request
        request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取前端请求参数
        String token = request.getHeader(securityConfigModel.getSignHead());
        // TODO 从缓存中获取token对应的用户信息
        Object user = TokenDecode.signDecode(securityConfigModel.getSignMsg(), token, redissonClient, securityConfigModel.getLoginValidUser());
        return user;
    }

    /**
     * 通过security黑盒子获取用户信息
     *
     * @return
     */
    public Object getSecurityUser(ServerHttpRequest request){
        // 获取前端请求参数
        String token = request.getHeaders().getFirst(securityConfigModel.getSignHead());
        // TODO 从缓存中获取token对应的用户信息
        Object user = TokenDecode.signDecode(securityConfigModel.getSignMsg(), token, redissonClient, securityConfigModel.getLoginValidUser());
        return user;
    }

    /**
     * 刷新用户黑盒数据
     *
     * @param user
     */
    public void refresh(Object user){
        // 获取request
        request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        setSecurity(user, request.getHeader(securityConfigModel.getSignHead()));
    }

    /**
     * 黑盒子缓存部署（默认有效1天）
     *
     * @param user
     * @param token
     */
    public void setSecurity(Object user, String token){
        // 有效时间换算
        Integer time = securityConfigModel.getLoginValidSign() * 24 * 60 * 60;
        RedissonUtil.set(redissonClient, token, JSON.toJSONString(user), time);
    }

    /**
     * 黑盒子缓存部署（自定义有效时间）
     *
     * @param user
     * @param token
     */
    public void setSecurity(Object user, String token, Long time){
        // token有效期（自定义）
        RedissonUtil.set(redissonClient, token, JSON.toJSONString(user), time);
    }

    /**
     * 登录注销
     */
    public void logout(){
        // 获取request
        request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取前端请求参数
        String token = request.getHeader(securityConfigModel.getSignHead());
        RedissonUtil.delete(redissonClient, token);
    }

    /**
     * token产生
     *
     * @param request
     * @param response
     * @return
     */
    public String signCreate(HttpServletRequest request, HttpServletResponse response){
        String token = securityConfigModel.getSignPrefix() + SnowflakeIdWorker.nextId();
        response.setHeader(securityConfigModel.getSignHead(), token);
        return token;
    }

}
